﻿using System;
using System.Collections.Generic;
using Model.Clientes;
using Infraestrutura.Repositorios.SQL;
using System.Configuration;
using System.Data.SqlClient;
using Model.Tipologias;

namespace Model.Contratos
{
    public class ContratoService : RepositorioSQL<Contrato>, IContratoService
    {
        
        public ContratoService()
        {
            Tabela = "Contratos";
            LigacaoBD = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
        }

        #region contrato

        public Contrato ObterPorNumeroContrato(Int64 numeroContrato)    
        {
            return ObterPorChave(String.Format("@NumeroContrato={0}", numeroContrato));
        }

        public IList<Contrato> ObterTodosPorCliente(Cliente cliente)
        {
            return ObterLista(String.Format("proc_ContratosLoadByIdCliente @IdCliente={0}", cliente.IdCliente));
        }

        public IList<Contrato> ObterTodosPorCliente(Int64 idCliente)
        {
            return ObterLista(String.Format("proc_ContratosLoadByIdCliente @IdCliente={0}", idCliente));
        }

        public IList<Contrato> ObterTodosActivosPorCliente(Cliente cliente)
        {
            return ObterLista(String.Format("proc_ContratosLoadActivosByIdCliente @IdCliente={0}", cliente.IdCliente));
        }

        public IList<Contrato> ObterTodosActivosPorCliente(Int64 idCliente)
        {
            return ObterLista(String.Format("proc_ContratosLoadActivosByIdCliente @IdCliente={0}", idCliente));
        }

        public IList<Contrato> ObterTodosFuturosPorCliente(Cliente cliente)
        {
            return ObterLista(String.Format("proc_ContratosLoadFuturosByIdCliente @IdCliente={0}", cliente.IdCliente));
        }

        public IList<Contrato> ObterTodosFuturosPorCliente(Int64 idCliente)
        {
            return ObterLista(String.Format("proc_ContratosLoadFuturosByIdCliente @IdCliente={0}", idCliente));
        }

        public IList<Contrato> ObterTodosTerminadosPorCliente(Cliente cliente)
        {
            return ObterLista(String.Format("proc_ContratosLoadTerminadosByIdCliente @IdCliente={0}", cliente.IdCliente));
        }

        public IList<Contrato> ObterTodosTerminadosPorCliente(Int64 idCliente)
        {
            return ObterLista(String.Format("proc_ContratosLoadTerminadosByIdCliente @IdCliente={0}", idCliente));
        }

        public IList<Contrato> ObterTodosActivos()
        {
            return ObterLista(String.Format("proc_ContratosLoadAllActivos"));
        }

        public IList<Contrato> ObterTodosActivosPorData(DateTime data)
        {
            return ObterLista(String.Format("proc_ContratosLoadAllActivosByData @Data='{0}'", data.ToString("yyyy-MM-ddTHH:mm:ss")));
        }

        public IList<Contrato> ObterTodosFuturos()
        {
            return ObterLista(String.Format("proc_ContratosLoadAllFuturos"));
        }

        public IList<Contrato> ObterTodosTerminados()
        {
            return ObterLista(String.Format("proc_ContratosLoadAllTerminados"));
        }

        public IList<Contrato> ObterComRefeicoesAbertasAte(DateTime data)
        {
            return ObterLista(String.Format("proc_ContratosByRefeicoesAbertasAte @DataRefeicao='{0}'", data.ToString("yyyy-MM-ddTHH:mm:ss")));
        }

        public IList<Contrato> ObterContratoTemRefeicoesAbertasAte(Int64 numeroContrato, DateTime data)
        {
            return ObterLista(String.Format("proc_ContratosByContratoRefAbertasAte @NumeroContrato={0},  @DataRefeicao='{1}'", numeroContrato, data.ToString("yyyy-MM-ddTHH:mm:ss")));
        }
        

        protected override Contrato CarregarDados(System.Data.SqlClient.SqlDataReader dataReader, Contrato item)
        {
            item.NumeroContrato = Convert.ToInt64(dataReader["NumeroContrato"]);
            item.DataContrato = Convert.ToDateTime(dataReader["DataContrato"]);
            
            Cliente cliente = new Cliente();
            cliente.IdCliente = Convert.ToInt64(dataReader["IdCliente"]);
            cliente.Nome = dataReader["Nome"].ToString();
            item.Cliente = cliente;
            
            Unidade unidade = new Unidade();
            unidade.Cliente = cliente;
            unidade.Designacao = dataReader["Designacao"].ToString();
            unidade.IdUnidade = Convert.ToInt64(dataReader["IdUnidade"]);
            unidade.Servico = Convert.ToBoolean(dataReader["Servico"]);
            item.Unidade = unidade;

            item.DataInicioContrato = Convert.ToDateTime(dataReader["DataInicioContrato"]);
            item.DataFimContrato = Convert.ToDateTime(dataReader["DataFimContrato"]); 
            //TODO: falta carregar dados das refeicoes;

            return item;
        }

        protected override string ObterParametrosInserir(Contrato item)
        {

            return String.Format("@NumeroContrato={0}, @IdCliente={1}, @IdUnidade={2}, @DataContrato='{3}', @DataInicioContrato='{4}', @DataFimContrato='{5}'",
                                   item.NumeroContrato, item.Cliente.IdCliente, item.Unidade.IdUnidade,
                                   item.DataContrato.ToString("yyyy-MM-ddTHH:mm:ss"), 
                                   item.DataInicioContrato.ToString("yyyy-MM-ddTHH:mm:ss"), 
                                   item.DataFimContrato.ToString("yyyy-MM-ddTHH:mm:ss"));
        }

        protected override string ObterParametrosApagar(Contrato item)
        {
            return String.Format("@NumeroContrato={0}",
                                  item.NumeroContrato);
        }

        #endregion

        #region RefeicaoContrato

        public RefeicaoContrato ObterRefeicaoPorIdRefeicaoContratada(Int64 IdRefeicaoContratada)
        {
            RefeicaoContrato item = null;

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_ContratosRefeicoesLoadByPrimaryKey @IdRefeicaoContratada={0}", IdRefeicaoContratada),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                if (reader.Read())
                {
                    item = new RefeicaoContrato();
                    item = CarregarDados(reader, item);
                }

                reader.Close();
            }

            return item;
        }

        
        public IList<RefeicaoContrato> ObterTodosRefeicaoPorContrato(Int64 numeroContrato)
        {
            IList<RefeicaoContrato> lista = new List<RefeicaoContrato>();

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_ContratosRefeicoesLoadAllByContrato @NumeroContrato={0}", numeroContrato),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                RefeicaoContrato item = null;
                while (reader.Read())
                {
                    item = new RefeicaoContrato();
                    lista.Add(CarregarDados(reader, item));
                }

                reader.Close();
            }

            return lista;
        
        }

        public RefeicaoContrato Actualiza(RefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosRefeicoesUpdate {0}", ObterParametrosActualizar(item)),
                    connection);

                command.Connection.Open();
                command.ExecuteScalar();
            }

            return item;
        }

        public RefeicaoContrato Insere(RefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosRefeicoesInsert {0}", ObterParametrosInserir(item)),
                    connection);

                command.Connection.Open();
                item.AtribuirChave(command.ExecuteScalar());
            }

            return item;
        }

        public void Apaga(RefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosRefeicoesDelete {0}", ObterParametrosApagar(item)),
                    connection);

                command.Connection.Open();
                command.ExecuteNonQuery();
            }
        }


        protected String ObterParametrosActualizar(RefeicaoContrato item)
        {
            return ObterParametrosInserir(item);
        }

        protected String ObterParametrosInserir(RefeicaoContrato item)
        {
            if (item.TipoClasseRefeicao != null)
                return String.Format("@NumeroContrato = {0}, @CodTipoRefeicao = '{1}', @CodTipoClasseRefeitorio = '{2}', @IdRefeicaoContratada = {3}",
                                      item.Contrato.NumeroContrato, item.TipoRefeicao.Codigo, item.TipoClasseRefeicao.Codigo, item.IdRefeicaoContratada);
            else
                return String.Format("@NumeroContrato = {0}, @CodTipoRefeicao = '{1}', @IdRefeicaoContratada = {2}",
                                      item.Contrato.NumeroContrato, item.TipoRefeicao.Codigo, item.IdRefeicaoContratada);
            
        }

        protected string ObterParametrosApagar(RefeicaoContrato item)
        {
            return String.Format("@IdRefeicaoContratada={0}",
                                  item.IdRefeicaoContratada);
        }


        private RefeicaoContrato CarregarDados(SqlDataReader dataReader, RefeicaoContrato item)
        {
            item.IdRefeicaoContratada = Convert.ToInt64(dataReader["IdRefeicaoContratada"]);
            item.Contrato = new Contrato();
            item.Contrato.NumeroContrato = Convert.ToInt64(dataReader["NumeroContrato"]);
            item.Contrato.DataContrato = Convert.ToDateTime(dataReader["DataContrato"]);
            item.Contrato.DataInicioContrato = Convert.ToDateTime(dataReader["DataInicioContrato"]);
            item.Contrato.DataFimContrato = Convert.ToDateTime(dataReader["DataFimContrato"]); 
            item.Contrato.Cliente = new Cliente(){IdCliente = Convert.ToInt64(dataReader["IdCliente"]), 
                                                  Nome = dataReader["Nome"].ToString() };
            item.Contrato.Unidade = new Unidade();
            item.Contrato.Unidade.IdUnidade = Convert.ToInt64(dataReader["IdUnidade"]);
            item.Contrato.Unidade.Designacao = dataReader["Designacao"].ToString();
            item.Contrato.Unidade.Servico = Convert.ToBoolean(dataReader["Servico"]);
            item.Contrato.Cliente = item.Contrato.Cliente;
            if (!Convert.IsDBNull(dataReader["UnidadePai"]))
                item.Contrato.Unidade.UnidadePai = new Unidade() { IdUnidade = Convert.ToInt64(dataReader["Servico"]) };

            item.TipoRefeicao = new Tipologia();
            item.TipoRefeicao.Codigo = dataReader["CodTipoRefeicao"].ToString();
            item.TipoRefeicao.Descricao = dataReader["DescricaoTipoRefeicao"].ToString();
            item.TipoRefeicao.DescricaoCurta = dataReader["DescricaoCurtaTipoRefeicao"].ToString();
            item.TipoRefeicao.Simbolo = dataReader["SimboloTipoRefeicao"].ToString();

            if (!Convert.IsDBNull(dataReader["CodTipoClasseRefeitorio"]))
            {
                item.TipoClasseRefeicao = new Tipologia();
                item.TipoClasseRefeicao.Codigo = dataReader["CodTipoClasseRefeitorio"].ToString();
                item.TipoClasseRefeicao.Descricao = dataReader["DescricaoClasseRefeicao"].ToString();
                item.TipoClasseRefeicao.DescricaoCurta = dataReader["DescricaoCurtaClasseRefeicao"].ToString();
                item.TipoClasseRefeicao.Simbolo = dataReader["SimboloClasseRefeicao"].ToString();
            }


            return item;
        }

        #endregion

        #region RefeicaoContratoOpcao

        public OpcaoRefeicaoContrato ObterOpcaoPorIdRefeicaoContratadaCodOpcao(Int64 idRefeicaoContratada, String codOpcao)
        {
            OpcaoRefeicaoContrato item = null;

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_ContratosOpcoesRefeicaoLoadByPrimaryKey @IdRefeicaoContratada={0}, @CodOpcao='{1}'",
                                 idRefeicaoContratada, codOpcao),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                if (reader.Read())
                {
                    item = new OpcaoRefeicaoContrato();
                    item = CarregarDados(reader, item);
                }

                reader.Close();
            }

            return item;
        }

        public IList<OpcaoRefeicaoContrato> ObterTodosOpcaoPorRefeicaoContratada(Int64 idRefeicaoContratada)
        {
            IList<OpcaoRefeicaoContrato> lista = new List<OpcaoRefeicaoContrato>();

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_ContratosOpcoesRefeicaoLoadByRefeicaoContratada @IdRefeicaoContratada={0}", idRefeicaoContratada),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                OpcaoRefeicaoContrato item = null;
                RefeicaoContrato refeicaoContrato = null;
                while (reader.Read())
                {
                    item = new OpcaoRefeicaoContrato();

                    if (refeicaoContrato != null)
                    {
                        lista.Add(CarregarDados(reader, item, refeicaoContrato));
                    }
                    else
                    {
                        lista.Add(CarregarDados(reader, item));
                        refeicaoContrato = item.RefeicaoContratada;
                    }

                }

                reader.Close();
            }

            return lista;
        
        }

        public OpcaoRefeicaoContrato Actualiza(OpcaoRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosOpcoesRefeicaoUpdate {0}", ObterParametrosActualizar(item)),
                    connection);

                command.Connection.Open();
                command.ExecuteScalar();
            }

            return item;
        }

        public OpcaoRefeicaoContrato Insere(OpcaoRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosOpcoesRefeicaoInsert {0}", ObterParametrosInserir(item)),
                    connection);

                command.Connection.Open();
                item.AtribuirChave(command.ExecuteScalar());
            }

            return item;
        }

        public void Apaga(OpcaoRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosOpcoesRefeicaoDelete {0}", ObterParametrosApagar(item)),
                    connection);

                command.Connection.Open();
                command.ExecuteNonQuery();
            }
        }

        protected String ObterParametrosActualizar(OpcaoRefeicaoContrato item)
        {
            return ObterParametrosInserir(item);
        }

        protected String ObterParametrosInserir(OpcaoRefeicaoContrato item)
        {

            return String.Format("@IdRefeicaoContratada = {0}, @CodOpcao = '{1}', @Descricao = '{2}'",
                                      item.RefeicaoContratada.IdRefeicaoContratada, 
                                      item.TipoOpcao.Codigo, 
                                      item.Descricao);
        }

        protected String ObterParametrosApagar(OpcaoRefeicaoContrato item)
        {
            return String.Format("@IdRefeicaoContratada={0}, @CodOpcao='{1}'",
                                  item.RefeicaoContratada.IdRefeicaoContratada, item.TipoOpcao.Codigo);
        }


        private OpcaoRefeicaoContrato CarregarDados(SqlDataReader dataReader, OpcaoRefeicaoContrato item)
        {
           return CarregarDados(dataReader, item,
               ObterRefeicaoPorIdRefeicaoContratada(Convert.ToInt64(dataReader["IdRefeicaoContratada"])));
        }

        private OpcaoRefeicaoContrato CarregarDados(SqlDataReader dataReader, OpcaoRefeicaoContrato item, RefeicaoContrato refeicaoContrato)
        {
            item.Descricao = dataReader["Descricao"].ToString();
            item.RefeicaoContratada = refeicaoContrato;
            item.TipoOpcao = new Tipologia();
            item.TipoOpcao.Tipo = dataReader["TipoOpcao"].ToString();
            item.TipoOpcao.Codigo = dataReader["CodOpcao"].ToString();
            item.TipoOpcao.Descricao = dataReader["DescricaoOpcao"].ToString();
            item.TipoOpcao.DescricaoCurta = dataReader["DescricaoCurtaOpcao"].ToString();
            item.TipoOpcao.Simbolo = dataReader["SimboloOpcao"].ToString();

            return item;
        }


        #endregion

        #region RefeicaoContratoPreco

        public PrecoRefeicaoContrato ObterPrecoPorIdRefeicaoContratadaCodTipoPreco(Int64 idRefeicaoContratada, String codTipoServico)
        {
            PrecoRefeicaoContrato item = null;

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_ContratosRefeicoesPrecoLoadByPrimaryKey @IdRefeicaoContratada={0}, @CodTipoServico='{1}'",
                                 idRefeicaoContratada, codTipoServico),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                if (reader.Read())
                {
                    item = new PrecoRefeicaoContrato();
                    item = CarregarDados(reader, item);
                }

                reader.Close();
            }

            return item;
        }

        public IList<PrecoRefeicaoContrato> ObterTodosPrecoPorRefeicaoContratada(Int64 idRefeicaoContratada)
        {
            IList<PrecoRefeicaoContrato> lista = new List<PrecoRefeicaoContrato>();

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_ContratosRefeicoesPrecoLoadByRefeicaoContratada @IdRefeicaoContratada={0}", idRefeicaoContratada),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                PrecoRefeicaoContrato item = null;
                RefeicaoContrato refeicaoContrato = null;
                while (reader.Read())
                {
                    item = new PrecoRefeicaoContrato();

                    if (refeicaoContrato != null)
                    {
                        lista.Add(CarregarDados(reader, item, refeicaoContrato));
                    }
                    else
                    {
                        lista.Add(CarregarDados(reader, item));
                        refeicaoContrato = item.RefeicaoContratada;
                    }

                }

                reader.Close();
            }

            return lista;

        }

        public PrecoRefeicaoContrato Actualiza(PrecoRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosRefeicoesPrecoUpdate {0}", ObterParametrosActualizar(item)),
                    connection);

                command.Connection.Open();
                command.ExecuteScalar();
            }

            return item;
        }

        public PrecoRefeicaoContrato Insere(PrecoRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosRefeicoesPrecoInsert {0}", ObterParametrosInserir(item)),
                    connection);

                command.Connection.Open();
                item.AtribuirChave(command.ExecuteScalar());
            }

            return item;
        }

        public void Apaga(PrecoRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_ContratosRefeicoesPrecoDelete {0}", ObterParametrosApagar(item)),
                    connection);

                command.Connection.Open();
                command.ExecuteNonQuery();
            }
        }

        protected String ObterParametrosActualizar(PrecoRefeicaoContrato item)
        {
            return ObterParametrosInserir(item);
        }

        protected String ObterParametrosInserir(PrecoRefeicaoContrato item)
        {

            return String.Format("@IdRefeicaoContratada = {0}, @CodTipoServico = '{1}', @Preco = {2}",
                                      item.RefeicaoContratada.IdRefeicaoContratada,
                                      item.TipoServico.Codigo,
                                      item.Preco);
        }

        protected string ObterParametrosApagar(PrecoRefeicaoContrato item)
        {
            return String.Format("@IdRefeicaoContratada={0}, @CodTipoServico='{1}'",
                                  item.RefeicaoContratada.IdRefeicaoContratada, item.TipoServico.Codigo);
        }


        private PrecoRefeicaoContrato CarregarDados(SqlDataReader dataReader, PrecoRefeicaoContrato item)
        {
            return CarregarDados(dataReader, item,
                ObterRefeicaoPorIdRefeicaoContratada(Convert.ToInt64(dataReader["IdRefeicaoContratada"])));
        }

        private PrecoRefeicaoContrato CarregarDados(SqlDataReader dataReader, PrecoRefeicaoContrato item, RefeicaoContrato refeicaoContrato)
        {
            item.Preco = Convert.ToDecimal(dataReader["Preco"]);
            item.RefeicaoContratada = refeicaoContrato;
            item.TipoServico = new Tipologia();
            item.TipoServico.Tipo = dataReader["TipoServico"].ToString();
            item.TipoServico.Codigo = dataReader["CodTipoServico"].ToString();
            item.TipoServico.Descricao = dataReader["DescricaoTipoServico"].ToString();
            item.TipoServico.DescricaoCurta = dataReader["DescricaoCurtaTipoServico"].ToString();
            item.TipoServico.Simbolo = dataReader["SimboloTipoServico"].ToString();

            return item;
        }


        #endregion

        #region UnidadeRefeicaoContrato

        public UnidadeRefeicaoContrato ObterUnidadeRefeicaoContratoPorUnidadeRefeicao(Int64 idRefeicaoContratada, Int64 idUnidade)
        {
            UnidadeRefeicaoContrato item = null;

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_UnidadesContratosRefeicoesLoadByPrimaryKey @IdRefeicaoContratada={0}, @IdUnidade={1}",
                                 idRefeicaoContratada, idUnidade),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                if (reader.Read())
                {
                    item = new UnidadeRefeicaoContrato();
                    item = CarregarDados(reader, item);
                }

                reader.Close();
            }

            return item;
        }

        public IList<UnidadeRefeicaoContrato> ObterUnidadeRefeicaoContratoPorUnidade(Int64 idUnidade)
        {
            IList<UnidadeRefeicaoContrato> lista = new List<UnidadeRefeicaoContrato>();

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_UnidadesContratosRefeicoesLoadByUnidade @IdUnidade={0}", idUnidade),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                UnidadeRefeicaoContrato item = null;
                RefeicaoContrato refeicaoContrato = null;
                while (reader.Read())
                {
                    item = new UnidadeRefeicaoContrato();

                    lista.Add(CarregarDados(reader, item));
                    refeicaoContrato = item.RefeicaoContrato;
                }

                reader.Close();
            }

            return lista;
        }


        public IList<UnidadeRefeicaoContrato> ObterUnidadesRefeicaoContratoPorRefeicaoContratada(Int64 idRefeicaoContratada)
        {
            IList<UnidadeRefeicaoContrato> lista = new List<UnidadeRefeicaoContrato>();

            using (SqlConnection sqlConnection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                  String.Format("exec proc_UnidadesContratosRefeicoesLoadUnidadesByRefeicaoContratada @IdRefeicaoContratada={0}", idRefeicaoContratada),
                  sqlConnection);

                sqlConnection.Open();

                SqlDataReader reader = command.ExecuteReader();

                UnidadeRefeicaoContrato item = null;
                RefeicaoContrato refeicaoContrato = null;
                while (reader.Read())
                {
                    item = new UnidadeRefeicaoContrato();

                    if (refeicaoContrato != null)
                    {
                        lista.Add(CarregarDados(reader, item, refeicaoContrato));
                    }
                    else
                    {
                        lista.Add(CarregarDados(reader, item));
                        refeicaoContrato = item.RefeicaoContrato;
                    }

                }

                reader.Close();
            }

            return lista;
        }

        public UnidadeRefeicaoContrato Actualiza(UnidadeRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_UnidadesContratosRefeicoesUpdate {0}", ObterParametrosActualizar(item)),
                    connection);

                command.Connection.Open();
                command.ExecuteScalar();
            }

            return item;
        }

        public UnidadeRefeicaoContrato Insere(UnidadeRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_UnidadesContratosRefeicoesInsert {0}", ObterParametrosInserir(item)),
                    connection);

                command.Connection.Open();
                item.AtribuirChave(command.ExecuteScalar());
            }

            return item;
        }

        public void Apaga(UnidadeRefeicaoContrato item)
        {
            using (SqlConnection connection = new SqlConnection(LigacaoBD))
            {
                SqlCommand command = new SqlCommand(
                    String.Format("exec proc_UnidadesContratosRefeicoesDelete {0}", ObterParametrosApagar(item)),
                    connection);

                command.Connection.Open();
                command.ExecuteNonQuery();
            }
        }

        protected string ObterParametrosApagar(UnidadeRefeicaoContrato item)
        {
            return String.Format("@IdRefeicaoContratada={0}, @IdUnidade={1}",
                                  item.RefeicaoContrato.IdRefeicaoContratada, item.Unidade.IdUnidade);
        }

        protected String ObterParametrosInserir(UnidadeRefeicaoContrato item)
        {
            String sqlParam = String.Empty;
            if (item.TipoServico != null)
            {
                sqlParam = String.Format("@IdRefeicaoContratada = {0}, @IdUnidade = {1}, @CodTipoServico = '{2}'",
                                      item.RefeicaoContrato.IdRefeicaoContratada,
                                      item.Unidade.IdUnidade,
                                      item.TipoServico.Codigo);

            }
            else {
                sqlParam = String.Format("@IdRefeicaoContratada = {0}, @IdUnidade = {1}",
                                      item.RefeicaoContrato.IdRefeicaoContratada,
                                      item.Unidade.IdUnidade);

            }

            return sqlParam;
        }

        protected String ObterParametrosActualizar(UnidadeRefeicaoContrato item)
        {
            return ObterParametrosInserir(item);
        }

        private UnidadeRefeicaoContrato CarregarDados(SqlDataReader dataReader, UnidadeRefeicaoContrato item)
        {
            return CarregarDados(dataReader, item,
                ObterRefeicaoPorIdRefeicaoContratada(Convert.ToInt64(dataReader["IdRefeicaoContratada"])));
        }

        private UnidadeRefeicaoContrato CarregarDados(SqlDataReader dataReader, UnidadeRefeicaoContrato item, RefeicaoContrato refeicaoContrato)
        {
            item.Activa = Convert.ToBoolean(dataReader["Activa"]);
            item.RefeicaoContrato = refeicaoContrato;

            item.Unidade = new Unidade()
            {
                IdUnidade = Convert.ToInt64(dataReader["IdUnidade"]),
                Cliente = refeicaoContrato.Contrato.Cliente,
                Designacao = dataReader["DesignacaoUnidade"].ToString(),
                Servico = Convert.ToBoolean(dataReader["Servico"])
            };
            if (!Convert.IsDBNull(dataReader["UnidadePai"]))
            {
                item.Unidade.UnidadePai = new Unidade() 
                { 
                    IdUnidade = Convert.ToInt64(dataReader["UnidadePai"]) 
                };
            }
            

            if (!Convert.IsDBNull(dataReader["CodTipoServico"]))
            {
                item.TipoServico = new Tipologia();
                item.TipoServico.Tipo = dataReader["TipoTipoServico"].ToString();
                item.TipoServico.Codigo = dataReader["CodTipoServico"].ToString();
                item.TipoServico.Descricao = dataReader["DescricaoTipoServico"].ToString();
                item.TipoServico.DescricaoCurta = dataReader["DescricaoCurtaTipoServico"].ToString();
                item.TipoServico.Simbolo = dataReader["SimboloTipoServico"].ToString();
            }


            if (!Convert.IsDBNull(dataReader["CodTipoRefeicao"]))
            {
                item.TipoRefeicao = new Tipologia();
                item.TipoRefeicao.Tipo = dataReader["TipoTipoRefeicao"].ToString();
                item.TipoRefeicao.Codigo = dataReader["CodTipoRefeicao"].ToString();
                item.TipoRefeicao.Descricao = dataReader["DescricaoTipoRefeicao"].ToString();
                item.TipoRefeicao.DescricaoCurta = dataReader["DescricaoCurtaTipoRefeicao"].ToString();
                item.TipoRefeicao.Simbolo = dataReader["SimboloTipoRefeicao"].ToString();
            }


            if (!Convert.IsDBNull(dataReader["CodTipoClasseRefeitorio"]))
            {
                item.ClasseRefeicao = new Tipologia();
                item.ClasseRefeicao.Tipo = dataReader["TipoTipoClasse"].ToString();
                item.ClasseRefeicao.Codigo = dataReader["CodTipoClasseRefeitorio"].ToString();
                item.ClasseRefeicao.Descricao = dataReader["DescricaoTipoClasse"].ToString();
                item.ClasseRefeicao.DescricaoCurta = dataReader["DescricaoCurtaTipoClasse"].ToString();
                item.ClasseRefeicao.Simbolo = dataReader["SimboloTipoClasse"].ToString();
            }
            return item;
        }

        #endregion
    }
}
